package com.trade.dao.impl;

import com.trade.dao.*;
import com.trade.dao.listener.*;
import com.trade.data.*;
import com.trade.data.type.*;
import java.util.*;
import java.util.zip.*;
import java.text.*;
import com.trade.data.calculation.*;

import org.hibernate.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.text.*;

import java.io.*;

import org.apache.http.HttpException;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import org.supercsv.cellprocessor.*;
import org.supercsv.io.*;
import org.supercsv.cellprocessor.ift.*;
import org.supercsv.cellprocessor.constraint.*;
import org.supercsv.prefs.*;

import org.json.*;

import org.drools.runtime.StatefulKnowledgeSession;
import org.drools.runtime.rule.WorkingMemoryEntryPoint;
import org.drools.runtime.rule.QueryResults;
import org.drools.runtime.rule.QueryResultsRow;

import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;


public class LivePriceDAO extends BaseDAO implements ILivePriceDAO {

	private Session session = null;

	private IDroolFlowDAO droolFlowDAO;

	//Drools Class

	public LivePriceDAO() {

	}

	public void setDroolFlowDAO( IDroolFlowDAO droolFlowDAO){
		this.droolFlowDAO = droolFlowDAO;
	}


	//Google get price help
	/* &i=604800&p=40Y&    => Weekly
	*  &i=86400&p=1Y		=> Day
	*  &i=1800&p=30d		=> 30Min
	*  &i=120&p=3d			=> 2Min
	*
	*/


	/**
	 * This method return Index and Stock historical data.
	 *
	 */
	public synchronized List<HistoricalDataVO> getPrice(HistoricalDataFilterVO filterVO)
			throws Exception {
		List<HistoricalDataVO> instrumentHistList = new ArrayList<HistoricalDataVO>();

		DateFormat formatter = new SimpleDateFormat("hh:mma z");
		NumberFormat numberFormatter = NumberFormat.getInstance();

		try {
			HttpHost proxy = new HttpHost("test", 8443);
			DefaultHttpClient httpclient = new DefaultHttpClient();
			//httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,			proxy);
			// http://finance.google.com/finance/info?client=ig&q=NIFTY:SBIN,NIFTY:BHEL
			// http://www.google.com/finance/getprices?q=SBIN&x=NSE&i=120&p=10m&f=d,c,v,o,h,l&df=cpct&auto=1&ts=1352181525283&ei=fqSYUIDBFKrE0QGyBg

			String url = "http://finance.google.com/finance/info?client=ig&q=";

			StringBuffer sb = new StringBuffer();

			for (String ticker : filterVO.getTickerList()) {
				sb.append("NSE:" + ticker + ",");
			}

			url = url + sb.toString();

			System.out.println(url);

			HttpGet httpget = new HttpGet(url);

			httpget.getParams().setParameter("http.socket.timeout",
					new Integer(30000));

			httpget.setHeader("Host", "finance.google.com");
			httpget
					.setHeader(
							"User-Agent",
							"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12");
			httpget
					.setHeader("Accept",
							"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
			httpget.setHeader("Accept-Charset",
					"ISO-8859-1,utf-8;q=0.7,*;q=0.7");
			httpget.setHeader("Accept-Encoding", "gzip,deflate");
			httpget.setHeader("Accept-Language", "en-us,en;q=0.5");
			httpget.setHeader("Connection", "keep-alive");
			httpget.setHeader("Keep-Alive", "115");
			httpget.setHeader("Content-Type",
					"application/x-www-form-urlencoded; charset=UTF-8");

			HttpResponse response = httpclient.execute(httpget);

			GZIPInputStream zipIn = new GZIPInputStream(response.getEntity()
					.getContent());

			StringBuffer responseString = new StringBuffer();
			Scanner sc = new Scanner(zipIn);
			int j = 0;
			while (sc.hasNextLine()) {
				String data = sc.nextLine();
				if (j == 0) {
					data = data.replaceAll("//", "");
				}
				responseString.append(data);
			}

			System.out.println(responseString.toString());

			JSONArray jsonArray = new JSONArray(responseString.toString());

			for (int i = 0; i < jsonArray.length(); i++) {
				JSONObject jsonObject = jsonArray.getJSONObject(i);
				HistoricalDataVO histDataVO = null;

				if ("NIFTY".equals(jsonObject.getString("t"))) {
					histDataVO = new IndexIntradayDataVO();
				} else {
					histDataVO = new EquityIntradayDataVO();
				}

				histDataVO.setSymbol(jsonObject.getString("t"));
				histDataVO
						.setDate(formatter.parse(jsonObject.getString("ltt")));
				histDataVO.setClose(numberFormatter.parse(
						jsonObject.getString("l")).doubleValue());

				//droolFlowDAO.insertObject(histDataVO , filterVO.getInterval());
				//this.statefulKnowledgeSession.fireAllRules();

				instrumentHistList.add(histDataVO);

			}


		} catch (Exception e) {
			System.out.println("Equity - " + e);
			throw new Exception(e);
		} finally {
		}

		return instrumentHistList;
	}

	/**
	 * This method return Index and Stock historical data.
	 *
	 */
	public synchronized List<HistoricalDataVO> getClosePrices(HistoricalDataFilterVO filterVO)
			throws Exception {
		List<HistoricalDataVO> instrumentHistList = new ArrayList<HistoricalDataVO>();

		DateFormat formatter = new SimpleDateFormat("hh:mma z");
		NumberFormat numberFormatter = NumberFormat.getInstance();

		try {
			//HttpHost proxy = new HttpHost("test", 8443);
			DefaultHttpClient httpclient = new DefaultHttpClient();
			//httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,proxy);
			// COLUMNS=DATE,CLOSE,HIGH,LOW,OPEN,VOLUME
			// http://www.google.com/finance/getprices?q=SBIN&x=NSE&i=120&p=10m&f=d,c,v,o,h,l&df=cpct&auto=1&ts=1352181525283&ei=fqSYUIDBFKrE0QGyBg
			for (String symbol : filterVO.getTickerList()) {
				String url = "http://www.google.com/finance/getprices?q="+ symbol
						+"&i=" + filterVO.getInterval().getPeriodValue()
						+ "&p=" + filterVO.getInterval().getPeriod()
						+ "&f=d,o,h,l,c,v";

				System.out.println(url);

				HttpGet httpget = new HttpGet(url);

				httpget.getParams().setParameter("http.socket.timeout",
						new Integer(30000));

				httpget.setHeader("Host", "www.google.com");
				httpget
						.setHeader(
								"User-Agent",
								"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12");
				httpget
						.setHeader("Accept",
								"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
				httpget.setHeader("Accept-Charset",
						"ISO-8859-1,utf-8;q=0.7,*;q=0.7");
				httpget.setHeader("Accept-Encoding", "gzip,deflate");
				httpget.setHeader("Accept-Language", "en-us,en;q=0.5");
				httpget.setHeader("Connection", "keep-alive");
				httpget.setHeader("Keep-Alive", "115");
				// httpget.setHeader("Content-Type",
				// "application/x-www-form-urlencoded; charset=UTF-8");

				HttpResponse response = httpclient.execute(httpget);

				GZIPInputStream zipIn = new GZIPInputStream(response.getEntity()
						.getContent());

				StringBuffer responseString = new StringBuffer();
				Scanner sc = new Scanner(zipIn);
				int j = 0;
				String data = null;
				while (sc.hasNextLine()) {
					data = sc.nextLine();
					responseString.append(data + "\n");

					if (j++ > 7) {
						String arr[] = data.split(",");

						HistoricalDataVO histDataVO = new EquityIntradayDataVO();

						// COLUMNS=DATE,CLOSE,HIGH,LOW,OPEN,VOLUME
						if( arr.length > 4){
							histDataVO.setSymbol(symbol);
							histDataVO.setDate(new Date());
							histDataVO.setClose(Double.valueOf(arr[1]));
							histDataVO.setHigh(Double.valueOf(arr[2]));
							histDataVO.setLow(Double.valueOf(arr[3]));
							histDataVO.setOpen(Double.valueOf(arr[4]));
							histDataVO.setVolume(Double.valueOf(arr[5]));
							histDataVO.setIntervalTimeTypes( IntervalTimeTypes.T2_MIN  ); // Temporary set filterVO.getInterval()
						}else{
							continue;
						}

						if( histDataVO.getClose() == histDataVO.getHigh()
							&&
							histDataVO.getClose() == histDataVO.getLow()
							&&
							histDataVO.getClose() == histDataVO.getOpen()

							){
								System.out.println("Skip "+symbol +" Data close - "+ histDataVO.getClose() + ", high - "
									+ histDataVO.getHigh());
								continue;
						}

						System.out.println(symbol +" Data close - "+ histDataVO.getClose() + ", high - "
								+ histDataVO.getHigh());

						instrumentHistList.add(histDataVO);

						//droolFlowDAO.insertObject(histDataVO , filterVO.getInterval());
						//statefulKnowledgeSession.startProcess("com.trade.data.ruleflow");
						//statefulKnowledgeSession.fireAllRules();
					}

					Thread.sleep(10);
				}
			}

		} catch (Exception e) {
			System.out.println("Equity - " + e.toString());
			throw new Exception(e);
		} finally {
		}

		return instrumentHistList;
	}

	/**
	 * This method return Stock and Index Intraday prices
	 *
	 */
	public synchronized List<HistoricalDataVO> getIntradayClosePrices(
			HistoricalDataFilterVO filterVO) throws Exception {
		List<HistoricalDataVO> instrumentHistList = new ArrayList<HistoricalDataVO>();

		DateFormat formatter = new SimpleDateFormat("hh:mma z");
		NumberFormat numberFormatter = NumberFormat.getInstance();

		try {
			//HttpHost proxy = new HttpHost("test", 8443);
			DefaultHttpClient httpclient = new DefaultHttpClient();
			//httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,proxy);
			// COLUMNS=DATE,CLOSE,HIGH,LOW,OPEN,VOLUME
			// http://www.google.com/finance/getprices?q=SBIN&x=NSE&i=120&p=10m&f=d,c,v,o,h,l&df=cpct&auto=1&ts=1352181525283&ei=fqSYUIDBFKrE0QGyBg
			for (String symbol : filterVO.getTickerList()) {

				String url = "http://www.google.com/finance/getprices?q="+ symbol +"&i="
						+ filterVO.getInterval().getPeriodValue()
						+ "&p=" + filterVO.getInterval().getPeriod()
						+ "&f=d,o,h,l,c,v";

				System.out.println(""+url);

				HttpGet httpget = new HttpGet(url);

				httpget.getParams().setParameter("http.socket.timeout",
						new Integer(30000));

				httpget.setHeader("Host", "www.google.com");
				httpget
						.setHeader(
								"User-Agent",
								"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12");
				httpget
						.setHeader("Accept",
								"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
				httpget.setHeader("Accept-Charset",
						"ISO-8859-1,utf-8;q=0.7,*;q=0.7");
				httpget.setHeader("Accept-Encoding", "gzip,deflate");
				httpget.setHeader("Accept-Language", "en-us,en;q=0.5");
				httpget.setHeader("Connection", "keep-alive");
				httpget.setHeader("Keep-Alive", "115");
				// httpget.setHeader("Content-Type",
				// "application/x-www-form-urlencoded; charset=UTF-8");

				HttpResponse response = httpclient.execute(httpget);

				GZIPInputStream zipIn = new GZIPInputStream(response
						.getEntity().getContent());

				StringBuffer responseString = new StringBuffer();
				Scanner sc = new Scanner(zipIn);
				String data = null;
				while (sc.hasNextLine()) {
					data = sc.nextLine();
					responseString.append(data + "\n");
				}

				String arr[] = data.split(",");

				HistoricalDataVO histDataVO = new EquityIntradayDataVO();

				//For every 3 sec data use as a 2 min data till next 2 min data not received.
				/*if( filterVO.getInterval() == IntervalTimeTypes.T2_SEC){
					List<EquityIntradayDataVO>  equityList = getEquityIntradayData( new Object[]{ "SBIN" } );
					histDataVO = equityList != null && equityList.size() > 0 ? equityList.get(equityList.size() - 1) : null ;
				}*/

				// COLUMNS=DATE,CLOSE,HIGH,LOW,OPEN,VOLUME
				histDataVO.setSymbol(symbol);
				histDataVO.setDate(new Date());
				histDataVO.setClose(Double.valueOf(arr[1]));
				histDataVO.setHigh(Double.valueOf(arr[2]));
				histDataVO.setLow(Double.valueOf(arr[3]));
				histDataVO.setOpen(Double.valueOf(arr[4]));
				histDataVO.setVolume(Double.valueOf(arr[5]));
				histDataVO.setIntervalTimeTypes( IntervalTimeTypes.T2_MIN  ); // Temporary set filterVO.getInterval()

				if( histDataVO.getClose() == histDataVO.getHigh()
					&&
					histDataVO.getClose() == histDataVO.getLow()
					&&
					histDataVO.getClose() == histDataVO.getOpen()

					){
					System.out.println("Skip "+symbol +" Data close - "+ histDataVO.getClose() + ", high - "
						+ histDataVO.getHigh());
					continue;
				}

				instrumentHistList.add(histDataVO);

				//droolFlowDAO.insertObject(histDataVO , filterVO.getInterval());
				//statefulKnowledgeSession.startProcess("com.trade.data.ruleflow");
				//statefulKnowledgeSession.fireAllRules();

				System.out.println("SBIN Data close: "+ histDataVO.getClose()
						+ ", high: " + histDataVO.getHigh()
						+ ", low: "+ histDataVO.getLow()
						+ ", Interval: "+ histDataVO.getIntervalTimeTypes());

			}
		} catch (Exception e) {
			System.out.println("Equity - " + e.toString());
			throw new Exception(e);
		} finally {
		}

		return instrumentHistList;
	}




	private synchronized List<NameValuePair> getParam(Map<String, String> map) {
		List<NameValuePair> param = new ArrayList<NameValuePair>();
		Set<String> set = map.keySet();
		for (String s : set) {
			param.add(new BasicNameValuePair(s, map.get(s) != null ? map.get(s)
					: ""));
		}
		return param;
	}


}